package com.managertrade.controller;

import com.managertrade.common.ErrorCode;
import com.managertrade.common.Result;
import com.managertrade.common.ServiceException;
import com.managertrade.dto.vo.KlineWithIndicators;
import com.managertrade.service.impl.KlineService;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Comparator;
import java.util.List;

@RestController
@RequestMapping("/api/market")
public class MarketController {
    @Autowired
    private KlineService marketService;

    @GetMapping("/candles")
    public Result<List<KlineWithIndicators>> getCandles(
            @RequestParam String instId,
            @RequestParam(defaultValue = "1h") String bar,
            @RequestParam(defaultValue = "800") Integer limit, @RequestParam(defaultValue = "binance") String source,
            @RequestParam(required = false) Long start,@RequestParam(required = false) Long end
            ) {
        try {
            List<KlineWithIndicators> data = marketService.getKlineWithIndicators(instId, bar, limit,source,start,end);
            return Result.success(data);
        } catch (Exception e) {
            throw new ServiceException(ErrorCode.FAIL_TRADE_VIEW);
        }
    }

    @GetMapping("/candles/exportCandlesExcel")
    public void exportCandlesExcel(
            @RequestParam String instId,
            @RequestParam(defaultValue = "1h") String bar,
            @RequestParam(defaultValue = "800") Integer limit,
            @RequestParam(defaultValue = "binance") String source,
            @RequestParam(required = false) Long start,
            @RequestParam(required = false) Long end,
            HttpServletResponse response
    ) throws Exception {

        List<KlineWithIndicators> data = marketService.getKlineWithIndicators(instId, bar, limit, source, start, end);
        data.sort(Comparator.comparingLong(KlineWithIndicators::getTimestamp));

        // 设置响应头，UTF-8 BOM 防止 Excel 打不开列
        String fileName = URLEncoder.encode(instId + "_kline_" + bar + ".csv", "UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
        response.setContentType("text/csv;charset=UTF-8");

        // 写入 BOM
        ServletOutputStream out = response.getOutputStream();
        out.write(0xEF);
        out.write(0xBB);
        out.write(0xBF);

        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));

        // 表头
        String[] headers = {"symbol", "period", "uniqueId", "dateTime",
                "timestamp", "open", "high", "low", "close", "volume",
                "ema7", "ema21", "macd", "signal", "histogram",
                "bollUpper", "bollMiddle", "bollLower"};
        writer.write(String.join(",", headers));
        writer.write("\r\n"); // Windows 换行

        // 数据
        for (KlineWithIndicators k : data) {
            writer.write(String.join(",",
                    escapeCsv(k.getSymbol()),
                    escapeCsv(k.getPeriod()),
                    escapeCsv(k.getUniqueId()),
                    escapeCsv(k.getDatetime()),
                    String.valueOf(k.getTimestamp()),
                    String.valueOf(k.getOpen()),
                    String.valueOf(k.getHigh()),
                    String.valueOf(k.getLow()),
                    String.valueOf(k.getClose()),
                    String.valueOf(k.getVolume()),
                    String.valueOf(k.getEma7() != null ? k.getEma7() : 0),
                    String.valueOf(k.getEma21() != null ? k.getEma21() : 0),
                    String.valueOf(k.getMacd() != null ? k.getMacd() : 0),
                    String.valueOf(k.getSignal() != null ? k.getSignal() : 0),
                    String.valueOf(k.getHistogram() != null ? k.getHistogram() : 0),
                    String.valueOf(k.getBollUpper() != null ? k.getBollUpper() : 0),
                    String.valueOf(k.getBollMiddle() != null ? k.getBollMiddle() : 0),
                    String.valueOf(k.getBollLower() != null ? k.getBollLower() : 0)
            ));
            writer.write("\r\n");
        }

        writer.flush();
        writer.close();
    }
    // 工具方法：处理 CSV 字段
// CSV 转义方法
    private String escapeCsv(String value) {
        if (value == null) return "";
        if (value.contains(",") || value.contains("\"") || value.contains("\n")) {
            value = value.replace("\"", "\"\"");
            return "\"" + value + "\"";
        }
        return value;
    }
}
